package com.talkweb.securitycamera.data.hadoopFile;

import com.talkweb.securitycamera.common.constans.FileType;
import com.talkweb.securitycamera.common.interfaces.dataprocess.IFileGet;
import com.talkweb.securitycamera.common.interfaces.dataprocess.IFileProcessor;
import com.talkweb.securitycamera.data.bean.MediaEntity;
import com.talkweb.securitycamera.utils.TimeUtils;
import ohos.app.Context;
import ohos.media.photokit.metadata.AVMetadataHelper;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

/**
 * 查询媒体文件与插入媒体文件的基类
 * Base Class of query Media Files and Insert Media Files
 *
 * @author : frank
 * @date : 2021/2/2 11:29
 */
public abstract class BaseMediaProcessor<T> implements IFileProcessor<MediaEntity, T>, IFileGet {

    public abstract Context getContext();

    @Override
    public List<MediaEntity> getFileList(FileType type) {
        List<MediaEntity> fileList = new ArrayList<>();
        AVMetadataHelper avMetadataHelper = new AVMetadataHelper();
        File mediaDirectory = MediaDirectoryProvider.provideMediaDirectory(getContext(), type);
        File[] rawFiles = mediaDirectory.listFiles();

        generateMediaEntityList(fileList, avMetadataHelper, rawFiles, type);

        return fileList;
    }

    @Override
    public List<MediaEntity> getFileListByTime(long startTime, long endTime, FileType type) {
        List<MediaEntity> fileList = new ArrayList<>();
        AVMetadataHelper avMetadataHelper = new AVMetadataHelper();
        File mediaDirectory = MediaDirectoryProvider.provideMediaDirectory(getContext(), type);
        File[] rawFiles = mediaDirectory.listFiles((dir, fileName) -> {
            int index = fileName.indexOf(".");
            String simpleName = fileName.substring(0, index);
            Long time = TimeUtils.getLongTime(simpleName);
            return time >= startTime && time <= endTime;
        });

        generateMediaEntityList(fileList, avMetadataHelper, rawFiles, type);

        return fileList;
    }

    @Override
    public List<MediaEntity> getFileListByKeyword(String keyword, FileType type) {
        List<MediaEntity> fileList = new ArrayList<>();
        AVMetadataHelper avMetadataHelper = new AVMetadataHelper();
        File mediaDirectory = MediaDirectoryProvider.provideMediaDirectory(getContext(), type);
        File[] rawFiles = mediaDirectory.listFiles((dir, fileName) -> fileName.contains(keyword));

        generateMediaEntityList(fileList, avMetadataHelper, rawFiles, type);

        return fileList;
    }

    private void generateMediaEntityList(List<MediaEntity> fileList, AVMetadataHelper avMetadataHelper, File[] rawFiles, FileType type) {
        for (File rawFile : rawFiles) {
            MediaEntity mediaEntity = new MediaEntity();
            mediaEntity.setType(type);
            mediaEntity.setCreateTime(rawFile.lastModified());
            mediaEntity.setFileName(rawFile.getName());
            mediaEntity.setFilePath(rawFile.getPath());

            if (type == FileType.FILE_TYPE_VIDEO) {
                avMetadataHelper.setSource(rawFile.getAbsolutePath());
                String duration = avMetadataHelper.resolveMetadata(AVMetadataHelper.AV_KEY_DURATION);
                mediaEntity.setCreateDuration(duration);
            }
            fileList.add(mediaEntity);
        }
    }

    @Override
    public void addFile(T source, FileType type) {
        //TODO 写之前检测内存，判断分布式文件空间是否满足需求
        //TODO 策略，优先删除视频文件

    }

    /**
     * 检测内存
     *
     * @param memoryPolicy 内存策略
     * @param ctx          上下文
     */
    protected void checkMemory(IMemoryPolicy memoryPolicy, Context ctx) {
        //新增文件前判断是否内存足够
        if (memoryPolicy != null && memoryPolicy.isMemInfoOut()) {
            memoryPolicy.cleanMemory(ctx, FileType.FILE_TYPE_IMAGE);
        }
    }
}
